/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package classes;

import java.awt.List;
import java.io.File;
import java.io.IOException;
import static java.lang.Integer.parseInt;
import java.util.ArrayList;
import javax.swing.JOptionPane;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
/**
 *
 * @author Joni
 */
public class SecureSharing {

    /**
     * @param args the command line arguments
     */
    
    private int id;
    private String username;
    private String encryptedPassword;
    private String certeficate;
    private String certificatePath;
    private String certificatePfx;
   // private String publicKey; 
   // private String privateKey; 
    private final String path; //sera o caminho da pasta na drop (eventualmente sera substituido para escrever na drop directamente)
    File xmlFile;
    
    public SecureSharing(String g) {
        path=g;
        System.out.print(g);
        xmlFile = new File(path +"\\users.xml");
        if (!xmlFile.exists()){
            JOptionPane.showMessageDialog(null,"Não foi encontrado um xml na pasta indicada. Será criado um");
            createXML();
        }
    }
    
    private void createXML(){
        try{
            DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); 

            //root element
            Document doc = docBuilder.newDocument();
            Element rootElement = doc.createElement("USERS"); 
            doc.appendChild(rootElement);
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            DOMSource source = new DOMSource(doc);
            StreamResult result = new StreamResult(new File(path+"\\users.xml"));

            transformer.transform(source, result);
         } catch (ParserConfigurationException pce) {
                pce.printStackTrace();
          } catch (TransformerException tfe) {
                tfe.printStackTrace();
          }    
    }
    
    public  void addUser(String newUsername, String newPassword, String newCertificateCerName, String newCertificatePfxName) throws TransformerException, SAXException, IOException {
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(xmlFile);

            doc.getDocumentElement().normalize();
            NodeList nodeList = doc.getElementsByTagName("USERS");
            
            //root element

            
            //user Elements
            Element user = doc.createElement("User"); 
            nodeList.item(0).appendChild(user);
            
            //set atribute to user element 
            Attr attr = doc.createAttribute("id");
            attr.setValue(getNewId()); //alterar valor 
            user.setAttributeNode(attr);
            
            //username element 
            Element usernameElement = doc.createElement("username"); 
            usernameElement.appendChild(doc.createTextNode(newUsername));
            user.appendChild(usernameElement); 
            
             //passord element 
            Element passwordElement = doc.createElement("password"); 
            passwordElement.appendChild(doc.createTextNode(newPassword));//tem de ser alterado para encriptar a pass antes
            user.appendChild(passwordElement);
            Element filesElement = doc.createElement("FILES"); 
            user.appendChild(filesElement);
            
             //publicKey element 
          /*  Element publicKeyElement = doc.createElement("publicKey"); 
            publicKeyElement.appendChild(doc.createTextNode(newPublicKey));
            user.appendChild(publicKeyElement);
            
              //privateKey element 
            Element privateKeyElement = doc.createElement("privateKey"); 
            privateKeyElement.appendChild(doc.createTextNode(newPrivateKey)); //tem de ser alterado para encriptar a chave privada
            user.appendChild(privateKeyElement);*/
            
            Element certificateNameElement = doc.createElement("certificateCerName"); 
            certificateNameElement.appendChild(doc.createTextNode(newCertificateCerName)); //tem de ser alterado para encriptar a chave privada
            user.appendChild(certificateNameElement);
            
            Element certificatePfxNameElement = doc.createElement("certificatePfxName"); 
            certificatePfxNameElement.appendChild(doc.createTextNode(newCertificatePfxName)); //tem de ser alterado para encriptar a chave privada
            user.appendChild(certificatePfxNameElement);
            
            // write the content into xml file
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            DOMSource source = new DOMSource(doc);
            StreamResult result = new StreamResult(new File(path+"\\users.xml"));
            
            transformer.transform(source, result);
         } catch (ParserConfigurationException pce) {
		pce.printStackTrace();
	  } catch (TransformerException tfe) {
		tfe.printStackTrace();
	  }    
    }
    
     public List getAllUsers(){
        List l = new List();
         try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(xmlFile);

            doc.getDocumentElement().normalize();
            NodeList nodeList = doc.getElementsByTagName("User");
            for (int i=0; i<nodeList.getLength();i++)
            {
                Node node = nodeList.item(i);
                if (node.getNodeType()== Node.ELEMENT_NODE)
                {
                    Element element = (Element)node; 
                    String usernameAdd = element.getElementsByTagName("username").item(0).getTextContent();
                    if (!usernameAdd.equals(username)){
                     l.add(usernameAdd);
                    }
                }         
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
      return l;
    }
    
    public void addFileToUser(ArrayList<String> users, String fileName){
         try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(xmlFile);

            doc.getDocumentElement().normalize();
            NodeList nodeList = doc.getElementsByTagName("User");
            for (int i=0; i<nodeList.getLength();i++)
            {
                
                Node node = nodeList.item(i);
                if (node.getNodeType()== Node.ELEMENT_NODE)
                {
                    
                    Element element = (Element)node; 
                    String usernameInXml = element.getElementsByTagName("username").item(0).getTextContent();
                    for (Object listUser : users) {
                        if (listUser.toString().equals(usernameInXml) ){
                           // System.out.println("encontrei o user "+ usernameAdd + " no xml");
                            Element filesElement = (Element)element.getElementsByTagName("FILES").item(0);
                            Element file = doc.createElement("FILE"); 
                            file.appendChild(doc.createTextNode(fileName)); //tem de ser alterado para encriptar a chave privada
                            filesElement.appendChild(file);
                        }
                    }
                    
                }         
            }
            // write the content into xml file
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            DOMSource source = new DOMSource(doc);
            StreamResult result = new StreamResult(new File(path+"\\users.xml"));
            transformer.transform(source, result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
     
        public String getUserCertificate(String currentUsername){
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(xmlFile);

            doc.getDocumentElement().normalize();
            NodeList nodeList = doc.getElementsByTagName("User");
            for (int i=0; i<nodeList.getLength();i++)
            {
                Node node = nodeList.item(i);
                if (node.getNodeType()== Node.ELEMENT_NODE)
                {
                    Element element = (Element)node; 
                    username = element.getElementsByTagName("username").item(0).getTextContent();
                    if (username.equals(currentUsername)){
                     Element filesElement = (Element)element.getElementsByTagName("certificateCerName").item(0);
                     return filesElement.getTextContent();
                    }
                }         
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
      return null;
    }
    
    public boolean userExists(String currentUsername){
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(xmlFile);

            doc.getDocumentElement().normalize();
            NodeList nodeList = doc.getElementsByTagName("User");
            for (int i=0; i<nodeList.getLength();i++)
            {
                Node node = nodeList.item(i);
                if (node.getNodeType()== Node.ELEMENT_NODE)
                {
                    Element element = (Element)node; 
                    username = element.getElementsByTagName("username").item(0).getTextContent();
                    if (username.equals(currentUsername)){
                     return true;
                    }
                }         
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
      return false;
    }

    public  void readInXML(String currentUsername) {
     id = -1;
     username = null;
     encryptedPassword = null;
   /*  publicKey = null;
     privateKey = null;*/
     
     try {
       DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
       DocumentBuilder db = dbf.newDocumentBuilder();
       Document doc = db.parse(xmlFile);
       
       doc.getDocumentElement().normalize();
       NodeList nodeList = doc.getElementsByTagName("User");
       for (int i=0; i<nodeList.getLength();i++)
       {
           Node node = nodeList.item(i);
           if (node.getNodeType()== Node.ELEMENT_NODE)
           {
               Element element = (Element)node; 
               username = element.getElementsByTagName("username").item(0).getTextContent();
               if (username.equals(currentUsername)){
                id = parseInt(element.getAttribute("id"));    
                encryptedPassword = element.getElementsByTagName("password").item(0).getTextContent();
                certeficate = element.getElementsByTagName("certificateCerName").item(0).getTextContent();
                certificatePfx = element.getElementsByTagName("certificatePfxName").item(0).getTextContent();
             //   publicKey = element.getElementsByTagName("publicKey").item(0).getTextContent();
                //privateKey = element.getElementsByTagName("privateKey").item(0).getTextContent();
                break;
               }
           }         
       }
        } catch (Exception e) {
            e.printStackTrace();
        } 
    }
    
    public List getUserFiles(){
    List l = new List();
         try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(xmlFile);

            doc.getDocumentElement().normalize();
            NodeList nodeList = doc.getElementsByTagName("User");
            for (int i=0; i<nodeList.getLength();i++)
            {
                Node node = nodeList.item(i);
                if (node.getNodeType()== Node.ELEMENT_NODE)
                {
                    Element userElement = (Element)node; 
                    String usernameAdd = userElement.getElementsByTagName("username").item(0).getTextContent();
                    if (usernameAdd.equals(username)){
                        
                        Element filesElement = (Element)userElement.getElementsByTagName("FILES").item(0);
                        NodeList filesList = filesElement.getElementsByTagName("FILE");
                        for(int y=0; y<filesList.getLength();y++){
                                l.add(filesList.item(y).getTextContent());  
                        }
                    }
                }         
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
      return l;
    }
    
        public List getUserCanSeeFile(String file){
    List l = new List();
         try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(xmlFile);

            doc.getDocumentElement().normalize();
            NodeList nodeList = doc.getElementsByTagName("User");
            for (int i=0; i<nodeList.getLength();i++)
            {
                Node node = nodeList.item(i);
                if (node.getNodeType()== Node.ELEMENT_NODE)
                {
                    Element userElement = (Element)node; 
                    String usernameAdd = userElement.getElementsByTagName("username").item(0).getTextContent();
                    if (!usernameAdd.equals(username)){
                        
                        Element filesElement = (Element)userElement.getElementsByTagName("FILES").item(0);
                        NodeList filesList = filesElement.getElementsByTagName("FILE");
                        for(int y=0; y<filesList.getLength();y++){
                            if(filesList.item(y).getTextContent().equals(file))
                                l.add(usernameAdd);  
                        }
                    }
                }         
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
      return l;
    }
    
    public String getNewId() {
        id = -1;
        username = null;
        encryptedPassword = null;
      /*  publicKey = null;
        privateKey = null;*/
     
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(xmlFile);
       
            doc.getDocumentElement().normalize();
            NodeList nodeList = doc.getElementsByTagName("User");
            
            if(nodeList.getLength()==0)
                return "1";
                    
            for (int i=0; i<nodeList.getLength();i++){
                Node node = nodeList.item(i);
                if (node.getNodeType()== Node.ELEMENT_NODE){
                    Element element = (Element)node; 
                    if(id < parseInt(element.getAttribute("id")))
                        id = parseInt(element.getAttribute("id"));
                    
                }         
            }
        } catch (Exception e) {
            e.printStackTrace();
        } 
        return String.valueOf(id+1);
    }
    
    public boolean login(byte[] currentPassword){
        return encryptedPassword.equals(convertToHex(currentPassword));// tem de ser alterado para comparar as passes encriptadas
    }
    
    public int getId() {
        return id;
    }

    public String getUsername() {
        return username;
    }

    public String getEncryptedPassword() {
        return encryptedPassword;
    }
/*
    public String getPublicKey() {
        return publicKey;
    }
    
    public String getPrivateKey() {
        return privateKey;
    }*/

    public String getPath() {
        System.out.println("caminho da pasta: " +path);
        return path;
    }

    public String getCerteficate() {
        return certeficate;
    }

    

    public void setCerteficate(String certeficate) {
        this.certeficate = certeficate;
    }
    
    public static String convertToHex(byte[] data) { 
        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < data.length; i++) { 
            int halfbyte = (data[i] >>> 4) & 0x0F;
            int two_halfs = 0;
            do { 
                if ((0 <= halfbyte) && (halfbyte <= 9)) 
                    buf.append((char) ('0' + halfbyte));
                else 
                    buf.append((char) ('a' + (halfbyte - 10)));
                halfbyte = data[i] & 0x0F;
            } while(two_halfs++ < 1);
        } 
        return buf.toString();
    }
    
    
  }

  
       

   
    

